package com.foundersoftware.parser.excel.impl;

import java.io.File;
import java.io.FileOutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

import com.foundersoftware.exception.ParserExcelException;
import com.foundersoftware.parser.excel.IParserExcel;
import com.foundersoftware.template.excel.IParserTemplate;

/**
 * The parser excel.
 * @author	JiDong
 * @create	December 2.2009
 * 
 *
 */
public class ParserExcelImpl implements IParserExcel {
	
	private static final Log 	log = LogFactory.getLog(ParserExcelImpl.class);	
	private static final int 	STARTE_ROW = 3;	

	public boolean exportExcel(List<Object> exportData,IParserTemplate parserTemplate) {
		HSSFWorkbook workbook = parserTemplate.getWorkbook();
		if (null == workbook) {
			new ParserExcelException("Reader template obtain workbook is null.");
		}
		
		Map<String,String> parameterMap = new HashMap<String, String>();
		
		for (int i = 0; i< workbook.getNumberOfSheets(); i++) {
			HSSFSheet tempSheet = workbook.getSheetAt(i);
			internalObtainTemplateRow(tempSheet, parameterMap);
			
			if (parameterMap != null) {
				internalSetCellValue(exportData, tempSheet,parameterMap);
			}
		}
		
		createExcel(workbook);
		return true;
	}

	private void internalObtainTemplateRow(HSSFSheet tempSheet,
			Map<String, String> parameterMap) {
		for (Iterator<HSSFRow> rit = (Iterator<HSSFRow>)tempSheet.rowIterator(); rit.hasNext(); ) {
			HSSFRow tempRow = rit.next();
			int count = tempRow.getRowNum();
			if (count == STARTE_ROW) {	
				internalObtainParameter(tempRow, parameterMap);
			}
		}
	}
	
	private void createExcel(HSSFWorkbook workbook) {
		FileOutputStream outStream = null;
		try {
			if (null != workbook) {
				String path = getExprotExcelFileAddress();
				String time = getCurrentDate();
				path+=time+".xls";
				File file = new File(path);
				outStream = new FileOutputStream(file);  
				workbook.write(outStream);  
				
				file = null;
				time = null;
				path = null;
			}
			
		} catch (Exception e) {
			log.error("parser excel appear exception :"+e.getMessage()+" in class :"+e.getClass()+" stack :"+e.getStackTrace());
			new ParserExcelException(e);
		}finally{
			try {
				outStream.close();
			} catch (Exception e) {
				log.error("parser excel appear exception :"+e.getMessage()+" in class :"+e.getClass()+" stack :"+e.getStackTrace());
				new ParserExcelException(e);
			}
		}
	}
	
	private String getExprotExcelFileAddress(){
		ResourceBundle resourceBundle = ResourceBundle.getBundle("resourceBundle");
		return resourceBundle.getString("parser.excel.file.address");
	}
	
	private String getCurrentDate(){
		SimpleDateFormat dateFormate = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");
		return dateFormate.format(new Date());
	}
	
	private void internalSetCellValue(List<Object> exportData,HSSFSheet sheet,Map<String,String> parameterMap){
		for (int i = STARTE_ROW; i< exportData.size();i++) {
			HSSFRow row = sheet.getRow(i);
			if(row == null){
				row = sheet.createRow(i);
			}
			Object obj = exportData.get(i);
			internalMappingParameterElement(row, parameterMap,obj);
			
			row = null;
			obj = null;
		}
	}
	
	private Map<String,String> internalObtainParameter(HSSFRow tempRow, Map<String, String> parameterMap){
		for (Iterator<HSSFCell> cit = (Iterator<HSSFCell>)tempRow.cellIterator(); cit.hasNext(); ) {
			HSSFCell cell = cit.next();
			HSSFRichTextString value = cell.getRichStringCellValue();
			String key = cell.getColumnIndex()+"";
			internalObtainParameter(key, value.toString(), parameterMap);
		}
		return parameterMap;
	}

	private Map<String,String> internalObtainParameter(String key,String value, Map<String, String> parameterMap){
		parameterMap.put(key,value);			
		return parameterMap;
	}
	
	private void internalMappingParameterElement(HSSFRow row,Map<String,String> parameterMap,Object obj){
		try {
			for (int i = 0; i < parameterMap.size(); i++) {
				String parame = parameterMap.get(""+i+"");
				if (!"".equals(parame) && parame != null) {
					String value = BeanUtils.getSimpleProperty(obj,parame);
					HSSFCell  cell = row.getCell(i);
					if(cell == null){
						cell = row.createCell(i);
					}
					cell.setCellValue(new HSSFRichTextString(value));
				}
			}
		} catch (Exception e) {
			log.error("parser excel appear exception :"+e.getMessage()+" in class :"+e.getClass()+" stack :"+e.getStackTrace());
			new ParserExcelException(e);
		}  
	}

	public boolean importExcel(List<Object> lists) {
		return false;
	}
	
}
